import java.util.Vector;

/**
 * 1 英国人住在红色的房子里；
 * 2 瑞典人养狗作为宠物；
 * 3 丹麦人喝茶；
 * 4 绿房子紧挨着白房子，在白房子的左边；
 * 5 绿房子的主人喝咖啡；
 * 6 抽Pall Mall牌香烟的人养鸟；
 * 7 黄色房子里的人抽Dunhill牌香烟；
 * 8 住在中间那个房子里的人喝牛奶；
 * 9 挪威人住在第一个房子里面；
 * 10 抽Blends牌香烟的人和养猫的人相邻；
 * 11 养马的人和抽Dunhill牌香烟的人相邻；
 * 12 抽BlueMaster牌香烟的人喝啤酒；
 * 13 德国人抽Prince牌香烟；
 * 14 挪威人和住在蓝房子的人相邻；
 * 15 抽Blends牌香烟的人和喝矿泉水的人相邻
 *
 */
public class AiYinSiTan {

    enum COLOR {Yellow, Blue, Red, Green, White}
    enum NATION {Norway, Denmark, England, Germany, Sweden}
    enum DRINK {Water, Tea, Milk, Coffee, Beer}
    enum PET {Cat, Horse, Bird, Fish, Dog}
    enum CIGARETTE {Dunhill, Blends, PallMall, Prince, BlueMaster}

    static class Person {
        COLOR color;
        NATION nation;
        DRINK drink;
        PET pet;
        CIGARETTE cigarette;
        int index;    //在几号房子

        public Person(COLOR color, NATION nation, DRINK drink, PET pet, CIGARETTE cigarette, int index) {
            this.color = color;
            this.nation = nation;
            this.drink = drink;
            this.pet = pet;
            this.cigarette = cigarette;
            this.index = index;
        }

        public String toString() {
            return "Person{" +
                    "color=" + color +
                    ", nation=" + nation +
                    ", drink=" + drink +
                    ", pet=" + pet +
                    ", cigarette=" + cigarette +
                    ", index=" + index +
                    '}';
        }
    }


    boolean test1(final Person person) {
        return (person.color == COLOR.Red && person.nation == NATION.England) ||
                (person.color != COLOR.Red && person.nation != NATION.England);
    }

    boolean test2(final Person person) {
        return (person.nation == NATION.Sweden && person.pet == PET.Dog) ||
                (person.nation != NATION.Sweden && person.pet != PET.Dog);
    }

    boolean test3(final Person person) {
        return (person.nation == NATION.Denmark && person.drink == DRINK.Tea) ||
                (person.nation != NATION.Denmark && person.drink != DRINK.Tea);
    }

    boolean test5(final Person person) {
        return (person.color == COLOR.Green && person.drink == DRINK.Coffee) ||
                (person.color != COLOR.Green && person.drink != DRINK.Coffee);
    }

    boolean test6(final Person person) {
        return (person.cigarette == CIGARETTE.PallMall && person.pet == PET.Bird) ||
                (person.cigarette != CIGARETTE.PallMall && person.pet != PET.Bird);
    }

    boolean test7(final Person person) {
        return (person.color == COLOR.Yellow && person.cigarette == CIGARETTE.Dunhill) ||
                (person.color != COLOR.Yellow && person.cigarette != CIGARETTE.Dunhill);
    }

    boolean test8(final Person person) {
        return (person.index == 2 && person.drink == DRINK.Milk) ||
                (person.index != 2 && person.drink != DRINK.Milk);
    }

    boolean test9(final Person person) {
        return (person.index == 0 && person.nation == NATION.Norway) ||
                (person.index != 0 && person.nation != NATION.Norway);
    }

    boolean test12(final Person person) {
        return (person.cigarette == CIGARETTE.BlueMaster && person.drink == DRINK.Beer) ||
                (person.cigarette != CIGARETTE.BlueMaster && person.drink != DRINK.Beer);
    }

    boolean test13(final Person person) {
        return (person.nation == NATION.Germany && person.cigarette == CIGARETTE.Prince) ||
                (person.nation != NATION.Germany && person.cigarette != CIGARETTE.Prince);
    }

    boolean test14(final Person person) {
        return (person.color == COLOR.Blue && person.index == 1) ||
                (person.color != COLOR.Blue && person.index != 1);
    }

    Vector<Person> house0 = new Vector<>();
    Vector<Person> house1 = new Vector<>();
    Vector<Person> house2 = new Vector<>();
    Vector<Person> house3 = new Vector<>();
    Vector<Person> house4 = new Vector<>();

    public void search() {
        //先构造满足个体条件的人，然后加入不同的房子里，再对房子里面的人进行循环
        for (COLOR color : COLOR.values()) {
            for (NATION nation : NATION.values()) {
                for (DRINK drink : DRINK.values()) {
                    for (PET pet : PET.values()) {
                        for (CIGARETTE cigarette : CIGARETTE.values()) {
                            for (int index = 0; index < 5; index++) {
                                Person person = new Person(color, nation, drink, pet, cigarette, index);
                                //如果这个人满足个体条件，则加入对应的房子
                                if (test1(person) && test2(person) && test3(person) && test5(person) && test6(person) &&
                                        test7(person) && test8(person) && test9(person) && test12(person) &&
                                        test13(person) && test14(person)) {
                                    switch (person.index) {
                                        case 0:
                                            house0.add(person);
                                            break;
                                        case 1:
                                            house1.add(person);
                                            break;
                                        case 2:
                                            house2.add(person);
                                            break;
                                        case 3:
                                            house3.add(person);
                                            break;
                                        case 4:
                                            house4.add(person);
                                            break;
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

        //对5个房子里面的人进行循环
        for (Person person0 : house0) {
            for (Person person1 : house1) {
                for (Person person2 : house2) {
                    for (Person person3 : house3) {
                        for (Person person4 : house4) {
                            Person[] people = {person0, person1, person2, person3, person4};
                            if (test4(people) && test10(people) && test11(people) && test15(people) && isDistinct(people)) {
                                //找到了正确结果并输出
                                for (Person person : people) {
                                    System.out.println(person);
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    //判断这组人是否有状态重复。不重复的情况下应该每种属性的值只有一个人有
    private boolean isDistinct(Person... people) {
        boolean[] colors = new boolean[5];
        boolean[] nations = new boolean[5];
        boolean[] drinks = new boolean[5];
        boolean[] pets = new boolean[5];
        boolean[] cigarettes = new boolean[5];
        for (int i = 0; i < 5; i++) {
            colors[people[i].color.ordinal()] = true;
            nations[people[i].nation.ordinal()] = true;
            drinks[people[i].drink.ordinal()] = true;
            pets[people[i].pet.ordinal()] = true;
            cigarettes[people[i].cigarette.ordinal()] = true;
        }
        boolean result = true;
        for (int i = 0; i < 5; i++) {
            result &= (colors[i] && nations[i] && drinks[i] && pets[i] && cigarettes[i]);
        }
        return result;
    }

    private boolean test4(Person... people) {
        int green = 0;
        int white = 0;
        for (Person person : people) {
            if (person.color == COLOR.Green) green = person.index;
            if (person.color == COLOR.White) white = person.index;
        }
        return green + 1 == white;
    }

    private boolean test10(Person... people) {
        int blends = 0;
        int cat = 0;
        for (Person person : people) {
            if (person.cigarette == CIGARETTE.Blends) blends = person.index;
            if (person.pet == PET.Cat) cat = person.index;
        }
        return (blends + 1 == cat) || (blends - 1 == cat);
    }

    private boolean test11(Person... people) {
        int horse = 0;
        int dunhill = 0;
        for (Person person : people) {
            if (person.cigarette == CIGARETTE.Dunhill) dunhill = person.index;
            if (person.pet == PET.Horse) horse = person.index;
        }
        return (horse + 1 == dunhill) || (horse - 1 == dunhill);
    }

    private boolean test15(Person... people) {
        int blends = 0;
        int water = 0;
        for (Person person : people) {
            if (person.cigarette == CIGARETTE.Blends) blends = person.index;
            if (person.drink == DRINK.Water) water = person.index;
        }
        return (blends + 1 == water) || (blends - 1 == water);
    }

    public static void main(String[] args) {
        new AiYinSiTan().search();
    }
}
